package com.ceair.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ceair.entity.SysLog;
import com.ceair.entity.request.QueryLogExtReq;
import com.ceair.entity.request.QuerySysLogReq;
import com.ceair.entity.result.PageResult;
import com.ceair.entity.result.Result;
import com.ceair.entity.vo.LogExtVO;
import com.ceair.entity.vo.SysLogVO;
import com.ceair.service.ISysLogService;
import com.ceair.utils.structMapper.SysLogStructMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author wangbaohai
 * @ClassName SysLogController
 * @description: 业务日志接口
 * @date 2025年03月21日
 * @version: 1.0.0
 */
@RestController
@RequestMapping("/api/v1/syslog")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "业务日志管理", description = "业务日志相关接口")
public class SysLogController {

    private final ISysLogService sysLogService;

    /**
     * 分页查询业务日志信息
     *
     * 该函数用于根据查询条件分页获取系统日志信息，并将查询结果转换为视图对象列表返回。
     * 函数在执行前会进行权限校验，确保调用者具有访问该接口的权限。
     *
     * @param querySysLogReq 业务日志查询请求对象，包含分页和查询条件等信息，不能为空
     * @return 返回包含分页查询结果的PageResult对象，其中包含转换后的视图对象列表和总记录数
     */
    @PreAuthorize("hasAnyAuthority('/api/v1/syslog/page')")
    @Parameter(name = "querySysLogReq", description = "业务日志查询请求对象", required = true)
    @Operation(summary = "分页查询业务日志信息")
    @PostMapping("/page")
    public PageResult<List<SysLogVO>> querySysLogWithPage(@RequestBody QuerySysLogReq querySysLogReq) {
        // 调用服务层方法进行分页查询，获取系统日志的分页结果
        Page<SysLog> page = sysLogService.querySysLogWithPage(querySysLogReq);

        // 将查询结果中的实体对象列表转换为视图对象列表
        List<SysLogVO> list =
                Optional.ofNullable(page.getRecords()).orElse(Collections.emptyList()).parallelStream().map(record -> {
                            try {
                                // 使用映射器将实体对象转换为视图对象
                                return SysLogStructMapper.INSTANCE.toVO(record);
                            } catch (Exception e) {
                                // 记录转换失败的错误信息
                                log.error("转换业务日志信息失败 具体原因为 : {}", e.getMessage());
                                return null;
                            }
                        }).filter(Objects::nonNull)
                        .toList();

        // 返回包含转换后列表和列表大小的PageResult对象
        return PageResult.success(list, page.getTotal());
    }

    /**
     * 查询业务日志详情。
     *
     * 该方法通过调用服务层的 `querySysLogDetailById` 方法，根据传入的查询请求对象获取业务日志的详细信息。
     *
     * @param queryLogExtReq 业务日志详情查询请求对象，包含查询所需的参数信息。必填。
     * @return 返回一个封装了业务日志详情的结果对象 {@link Result<LogExtVO>}，其中包含查询到的日志信息。
     */
    @PreAuthorize("hasAnyAuthority('/api/v1/syslog/querySysLogDetailById')")
    @Parameter(name = "queryLogExtReq", description = "业务日志详情查询请求对象", required = true)
    @Operation(summary = "查询业务日志详情")
    @PostMapping("/querySysLogDetailById")
    public Result<LogExtVO> querySysLogDetailById(@RequestBody QueryLogExtReq queryLogExtReq) {
        // 调用服务层方法查询业务日志详情
        return Result.success(sysLogService.querySysLogDetailById(queryLogExtReq));
    }

}
